﻿using Nest;
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;

namespace ES.Client.Filter
{
    /// <summary>
    /// 顶层对象字段过滤器
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class RootObjectFieldBuilder<T> : BaseFilter<T>, IFilterBuilder where T : class
    {
        internal RootObjectFieldBuilder(string index, string docType)
        {
            this.Index = index;
            this.DocType = docType;
        }

        /// <summary>
        /// Based on script filter
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> EQ<TValue>(string field, TValue value)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// Based on script filter
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> NE<TValue>(string field, TValue value)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// Based on range filter, It only support number values and date values;
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> GT<TValue>(string field, TValue value)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// Based on range filter, It only support number values and date values;
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> GTE<TValue>(string field, TValue value)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// Based on range filter, It only support number values and date values;
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> LT<TValue>(string field, TValue value)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// Based on range filter, It only support number values and date values;
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="field"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> LTE<TValue>(string field, TValue value)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// 判断文档是否包含某个字段，字段值既不等于null也不等于空字符串
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> Exists(string field)
        {
            return this.IsNotNullAndEmpty(field);
        }

        /// <summary>
        /// 通过给定字段获取文档，字段值既不等于null也不等于空字符串
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> IsNotNullAndEmpty(string field)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            var script = string.Format("_source['{0}'] != null && !_source['{0}'].empty", field);
            containers.Add(Query<T>.Script(f => f.Inline(script)));
            return containers;
        }

        /// <summary>
        /// 判断文档是否不包含某个文档，字段值等于null或者等于空字符串
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> Missing(string field)
        {
            return this.IsNullOrEmpty(field);
        }

        /// <summary>
        /// 通过给定字段获取文档，字段值等于null或者等于空字符串
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> IsNullOrEmpty(string field)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            var script = string.Format("_source['{0}'] == null || _source['{0}'].empty", field);
            containers.Add(Query<T>.Script(f => f.Inline(script)));
            return containers;
        }

        /// <summary>
        /// 以特定前缀搜索
        /// </summary>
        /// <param name="field"></param>
        /// <param name="query"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> Prefix(string field, string query)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// 指定字段模糊搜索
        /// </summary>
        /// <param name="field"></param>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> Like(string field, string keyword)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// 正则表达式搜索
        /// </summary>
        /// <param name="field"></param>
        /// <param name="regex"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> Regex(string field, string regex)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }

        /// <summary>
        /// IN查询
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <param name="field"></param>
        /// <param name="values"></param>
        /// <returns></returns>
        public IEnumerable<QueryContainer> IN<TValue>(string field, IEnumerable<TValue> values)
        {
            List<QueryContainer> containers = new List<QueryContainer>();
            return containers;
        }
    }
}
